package com.zhuss.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.zhuss.common.SelectVo;
import com.zhuss.enums.EnumUtil;
import com.zhuss.enums.WeekDayAll;
import com.zhuss.util.bean.WeekDay;

public class DateUtil {

	public static final SimpleDateFormat sdfDateNoYear = new SimpleDateFormat("MM-dd ");
	public static final SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd ");
	public static final SimpleDateFormat sdfDateNoBlank = new SimpleDateFormat("yyyy-MM-dd");
	public static final SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	public static final SimpleDateFormat sdfTimeSecond = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static final SimpleDateFormat sdfTimeOnlyMinute = new SimpleDateFormat("HH:mm");
	
	public static String toDateTimeStrOnlyMinute(Long date) {
		String str = toDateTimeStrOnlyMinute(new Date(date));
		return str;
	}
	public static String toDateTimeStrOnlyMinute(Date date) {
		String str = sdfTimeOnlyMinute.format(date);
		return str;
	}
	
	
	public static List<Date> toDateListByTimeMinute(String startStr, String endStr, Integer minuteNum) {
		List<Date> dateList = new ArrayList<Date>();
		Date start = toDateByTimeMinute(startStr);
		Date end = toDateByTimeMinute(endStr);
		while (start.getTime() <= end.getTime()) {
			dateList.add(start);
			Calendar cal = Calendar.getInstance();
			cal.setTime(start);
			cal.add(Calendar.MINUTE, minuteNum);
			start = cal.getTime();
		}
		return dateList;
	}
	
	public static String toDateStrNoBlank(Date date) {
		String str = sdfDateNoBlank.format(date);
		return str;
	}
	
	public static String toDateStr(Date date) {
		String str = sdfDate.format(date);
		return str;
	}

	public static String toDateStrNoYear(Date date) {
		String str = sdfDateNoYear.format(date);
		return str;
	}
	
	public static String toDateTimeStr(Date date) {
		String str = sdfTime.format(date);
		return str;
	}
	
	public static String toDateTimeSecondStr(Date date) {
		String str = sdfTimeSecond.format(date);
		return str;
	}
	
	public static Long toDateLongByTimeMinute(String time) {
		return toDateByTimeMinute(time).getTime();
	}
	
	public static Date toYear20Later() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, 2050);
		Date year20Later = cal.getTime();
		return year20Later;
	}
	
	public static Date toDateByTimeMinute(String time) {
		Date today = new Date();
		String dateStr = sdfDate.format(today);
		try {
			return sdfTime.parse(dateStr + time);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static Long toNowDateLongNoHour() {
		return toNowDateNoHour().getTime();
	}
	
	public static Date toNowDateNoHour() {
		Date now;
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		now = cal.getTime();
		return now;
	}
	
	public static Date toMonthStart(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}
	
	public static Date toMonthEnd(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, 1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}
	
	public static Date toDateOnly(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}
	
	public static Date toDateOnlyMiddle(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 12);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	public static Date toDateOnlyEnd(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		cal.set(Calendar.MILLISECOND, 999);
		return cal.getTime();
	}

	public static Long getWeekSeq(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return Long.valueOf(cal.get(Calendar.WEEK_OF_YEAR));
	}


	public static List<WeekDay> toAll(Date start, Date end) {
		Calendar cal = Calendar.getInstance();
		start = DateUtil.toDateOnly(start);
		end = DateUtil.toDateOnly(end);
		cal.setTime(start);
		List<WeekDay> dayList = new ArrayList<WeekDay>();
		for (long l = start.getTime(); l <= end.getTime(); l += 1000 * 3600 * 24l) {
			WeekDay wd = new WeekDay();
			cal.setTime(new Date(l));
			wd.setDate(cal.getTime().getTime());
			wd.setWeekDay(EnumUtil.containsKey(WeekDayAll.class, cal.get(Calendar.DAY_OF_WEEK)));
			dayList.add(wd);
		}
		return dayList;
	}
	
	public static List<WeekDay> toWeekAll(Long weekSeq) {
		Calendar cal = Calendar.getInstance();
		Date date = DateUtil.toNowDateNoHour();
		cal.setTime(date);
		cal.set(Calendar.WEEK_OF_YEAR, weekSeq.intValue());
		cal.set(Calendar.DAY_OF_WEEK, WeekDayAll.周一.key());
		Integer year = cal.get(Calendar.YEAR);
		Integer weekYear = cal.getWeekYear();
		if (year < weekYear) {
			cal.add(Calendar.YEAR, 1);
		}
		List<WeekDay> weekDayList = new ArrayList<WeekDay>();
		List<SelectVo> selectVoList = EnumUtil.listSelect(com.zhuss.enums.WeekDayAll.class);
		for (SelectVo sv : selectVoList) {
			if (WeekDayAll.周日.sameKey(sv.getId())) {
				continue;
			}
			WeekDay wd = new WeekDay();
			cal.set(Calendar.DAY_OF_WEEK, sv.getId());
			wd.setDate(cal.getTime().getTime());
			wd.setWeekDay(sv.getName());
			weekDayList.add(wd);
		}
		WeekDay wd = new WeekDay();
		cal.set(Calendar.DAY_OF_WEEK, WeekDayAll.周日.key());
		cal.add(Calendar.WEEK_OF_YEAR, 1);
		wd.setDate(cal.getTime().getTime());
		wd.setWeekDay(WeekDayAll.周日.value());
		weekDayList.add(wd);
		return weekDayList;
	}
	
	public static List<WeekDay> toWeek(Long nextWeek) {
		Calendar cal = Calendar.getInstance();
		Date date = DateUtil.toNowDateNoHour();
		cal.setTime(date);
		cal.add(Calendar.WEEK_OF_YEAR, nextWeek.intValue());
		List<WeekDay> weekDayList = new ArrayList<WeekDay>();
		List<SelectVo> selectVoList = EnumUtil.listSelect(com.zhuss.enums.WeekDay.class);
		for (SelectVo sv : selectVoList) {
			WeekDay wd = new WeekDay();
			cal.set(Calendar.DAY_OF_WEEK, sv.getId() + 1);
			wd.setDate(cal.getTime().getTime());
			wd.setWeekDay(sv.getName());
			weekDayList.add(wd);
		}
		return weekDayList;
	}
	
	public static List<SelectVo> toWeekList(Long next) {
		List<SelectVo>  list = new ArrayList<SelectVo>();
		for (long i = 0l; i <= next; i ++) {
			List<WeekDay> week = toWeek(i);
			SelectVo item = new SelectVo((int)i, week.get(0).getDateStr() + "至 " + week.get(week.size() - 1).getDateStr(), i + "");
			list.add(item);
		}
		return list;
	}
	
	public static List<WeekDay> toWeek() {
		Calendar cal = Calendar.getInstance();
		Date date = DateUtil.toNowDateNoHour();
		cal.setTime(date);
		List<WeekDay> weekDayList = new ArrayList<WeekDay>();
		List<SelectVo> selectVoList = EnumUtil.listSelect(com.zhuss.enums.WeekDay.class);
		for (SelectVo sv : selectVoList) {
			WeekDay wd = new WeekDay();
			cal.set(Calendar.DAY_OF_WEEK, sv.getId() + 1);
			wd.setDate(cal.getTime().getTime());
			wd.setWeekDay(sv.getName());
			weekDayList.add(wd);
		}
		return weekDayList;
	}
	
	public static List<WeekDay> toWeek(Date now) {
		if (now == null) {
			now = DateUtil.toDateOnly(new Date());
		}
		Integer nextWeek = 0;
		Calendar cal = Calendar.getInstance();
		cal.setTime(now);
		Integer weekDay = cal.get(Calendar.DAY_OF_WEEK);
		if (weekDay.intValue() == 7) {
			nextWeek = 1;
		}
		List<WeekDay> weekDayList = new ArrayList<WeekDay>();
		privateToWeek(weekDayList, new HashMap<String, Date>(), nextWeek, now);
		return weekDayList;
	}
	
	public static void privateToWeek(List<WeekDay> weekDayList, Map<String, Date> weekDayMap, Integer nextWeek, Date now) {
		Calendar cal = Calendar.getInstance();
		if (now == null) {
			now = DateUtil.toNowDateNoHour();
		}
		cal.setTime(now);
		cal.add(Calendar.WEEK_OF_YEAR, nextWeek);
		
		List<SelectVo> selectVoList = null;
		selectVoList = EnumUtil.listSelect(com.zhuss.enums.WeekDay.class);
		
		for (SelectVo sv : selectVoList) {
			WeekDay wd = new WeekDay();
			cal.set(Calendar.DAY_OF_WEEK, sv.getId() + 1);
			wd.setDate(cal.getTime().getTime());
			wd.setWeekDay(sv.getName());
			weekDayList.add(wd);
			weekDayMap.put(wd.getWeekDay(), new Date(wd.getDate()));
		}
	}
	
	public static void privateToWeek2(List<WeekDay> weekDayList, Map<String, Date> weekDayMap, Integer nextWeek) {
		Calendar cal = Calendar.getInstance();
		Date date = DateUtil.toNowDateNoHour();
		cal.setTime(date);
		cal.add(Calendar.WEEK_OF_YEAR, nextWeek);
		
		List<SelectVo> selectVoList = null;
		selectVoList = EnumUtil.listSelect(com.zhuss.enums.WeekDay2.class);
		
		for (SelectVo sv : selectVoList) {
			WeekDay wd = new WeekDay();
			cal.set(Calendar.DAY_OF_WEEK, sv.getId() + 1);
			wd.setDate(cal.getTime().getTime());
			wd.setWeekDay(sv.getName());
			weekDayList.add(wd);
			weekDayMap.put(wd.getWeekDay(), new Date(wd.getDate()));
		}
	}
	
	public static Map<String, Date> toWeekMap(Integer nextWeek) {
		Map<String, Date> weekDayMap = new HashMap<String, Date>();
		privateToWeek(new ArrayList<WeekDay>(), weekDayMap, nextWeek, null);
		return weekDayMap;
	}
	
	public static Map<String, Date> toWeekMap2(Integer nextWeek) {
		Map<String, Date> weekDayMap = new HashMap<String, Date>();
		privateToWeek2(new ArrayList<WeekDay>(), weekDayMap, nextWeek);
		return weekDayMap;
	}
	
	
	public static List<Date> calculate(List<SelectVo> selectVoList) {
		List<Date> list = new ArrayList<>();
		for (SelectVo v : selectVoList) {
			String time = v.getName();
			Date date = DateUtil.toDateByTimeMinute(time);
			list.add(date);
		}
		return list;
	}
	
	public static Long calculateStart(List<SelectVo> selectVoList, Boolean next) {
		Long now = System.currentTimeMillis();
		Long nextStart = null;
		Long beforeStart = null;
		if (!next) {
			for (int i = selectVoList.size() - 1; i >= 0; i--) {
				SelectVo v = selectVoList.get(i);
				String time = v.getName();
				Long start = DateUtil.toDateLongByTimeMinute(time);
				if (start < now) {
					beforeStart = start;
					return beforeStart;
				}
			}
		}
		for (SelectVo v : selectVoList) {
			String time = v.getName();
			Long start = DateUtil.toDateLongByTimeMinute(time);
			if (start > now) {
				nextStart = start;
				return nextStart;
			}
		}
		return beforeStart;
	}
	
	
	public static Integer getWeekDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		Integer weekDay = cal.get(Calendar.DAY_OF_WEEK);
		return weekDay;
	}

	public static String getWeekDayName(Date date) {
		Integer weekDay = getWeekDay(date);
		String weekDayName = EnumUtil.containsKey(com.zhuss.enums.WeekDayAll.class, weekDay);
		return weekDayName;
	}

	public static String getNoon(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		Integer hour = cal.get(Calendar.HOUR_OF_DAY);
		String hourName = "";
		if (hour < 12) {
			hourName = "上午";
		}else {
			hourName = "下午";
		}
		return hourName;
	}

	public static String getNoon(Date start, Date end) {
		Calendar calStart = Calendar.getInstance();
		calStart.setTime(start);
		Integer startHour = calStart.get(Calendar.HOUR_OF_DAY);
		Calendar calEnd = Calendar.getInstance();
		calEnd.setTime(end);
		Integer endHour = calEnd.get(Calendar.HOUR_OF_DAY);
		String hourName = "";
		if (startHour < 12 && endHour < 12) {
			hourName = "上午";
		}
		if(startHour < 12 && endHour > 12) {
			hourName = "整天";
		}
		if(startHour > 12 && endHour > 12) {
			hourName = "下午";
		}
		return hourName;
	}

	public static void main(String[] args) throws ParseException {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//注意月份是MM
		Date date = simpleDateFormat.parse("2020-05-17 10:22:30");
		System.out.println(getWeekDayName(date));
		System.out.println(getNoon(new Date()));
		
		System.out.println(toWeek(new Date(new Date().getTime() + 1000 * 3600 * 24 * 11l)));
		
		System.out.println(toMonthStart(new Date()));
		System.out.println(toMonthEnd(new Date()));
		
		System.out.println(toDateOnlyMiddle(new Date(System.currentTimeMillis())));
	}

}
